package com.ls.io.rpc.transport;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.WriteBufferWaterMark;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.InetSocketAddress;
import java.util.concurrent.ConcurrentHashMap;

public class ClientFactory {

    static int poolSize = 1;

    static ConcurrentHashMap<InetSocketAddress, ClientPool> map = new ConcurrentHashMap<>();

    static Bootstrap bs = new Bootstrap();
    static {
        bs.group(new NioEventLoopGroup(1))
                .channel(NioSocketChannel.class)
//                .option(ChannelOption.SO_KEEPALIVE, true)
//                .option(ChannelOption.TCP_NODELAY, false)
//                .option(ChannelOption.SO_SNDBUF, 8000)
//                .option(ChannelOption.SO_RCVBUF, 8000)
//                .option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(1, 80000))
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline()
                                .addLast(new RpcMessageEncoder())
                                .addLast(new RpcMessageDecoder())
                                .addLast(new ResponseChannelHandler());
                    }
                });
    }


    public static ClientPool getPool(InetSocketAddress address){

        ClientPool clientPool = map.get(address);
        if(clientPool == null){
            map.putIfAbsent(address, new ClientPool(address, poolSize));
            clientPool = map.get(address);
        }

        return clientPool;
    }


    public static NioSocketChannel createClient(InetSocketAddress address){
        ChannelFuture connect = bs.connect(address);
        try {
            return (NioSocketChannel) connect.sync().channel();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }


}

